package com.xpec.c4.net;

import java.io.UnsupportedEncodingException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;

/**
 * @author zhangyuan
 * handler TGW packets
 */
public class XSENetTGWHandler extends SimpleChannelHandler 
{	
	/*
	 * wait for TGW tencent NAT packet
	 * 
	 * in http://wiki.open.qq.com/wiki/TGW%E6%8E%A5%E5%85%A5%E8%AF%B4%E6%98%8E
	 * for shrot http://tinyurl.com/ko2k4p9
	 */
	private static final Log log = LogFactory.getLog(XSENetTGWHandler.class);
	
	private boolean waitingForTGW = true;
	
	private static String TGW_MAGIC = "tgw_l7_forward";  
	private static String TGW_END = "\r\n\r\n";  
	
	public static Integer bytesIndexOf(byte[] source, byte[] pattern) 
	{
		boolean find = false;
		int i = 0;
		for(i = 0;i<=source.length-pattern.length;i++)
		{
			if(source[i]==pattern[0])
			{
				find = true;
			    for (int j = 0;j<pattern.length;j++)
			    {
			    	if (source[i+j]!=pattern[j])
			    	{
			          find = false;
			        }
			     }
			 }
		
			 if(find)
			 {
			      break;
			 }
		}
		
		if(!find)
		{
		    return new Integer(-1);
		}
		return  new Integer(i);
	}

	
	private boolean decodeTGW(ChannelBuffer buffer) throws UnsupportedEncodingException
	{
		//only decode with enough length
		if(buffer.readableBytes() > TGW_MAGIC.length())
		{
			byte[] bytes = new byte[buffer.readableBytes()];
			buffer.getBytes(0,bytes);
			
			int pos0 = bytesIndexOf(bytes,TGW_MAGIC.getBytes("US-ASCII"));
			int pos1 = bytesIndexOf(bytes,TGW_END.getBytes("US-ASCII"));
			
			if(pos0 < 0 || pos1 < 0)//not found
			{
				return false;
			}
			else
			{
				//treat pos1 as end of string
				byte[] _bytes = new byte[pos1 - pos0];
				buffer.getBytes(pos0,_bytes,0,_bytes.length);
				String str = new String(_bytes,"US-ASCII");
				log.error(str);
				buffer.readBytes(pos1 + 4);
				return true;
			}
		}
		else
		{
			return false;
		}
	}
	
	@Override
	public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception
	{
		if(waitingForTGW)
		{
			ChannelBuffer channelBuffer = (ChannelBuffer) e.getMessage();
			if(false == decodeTGW(channelBuffer))
			{
				return;
			}
			else
			{
				waitingForTGW = false;
			}
		}
		ctx.sendUpstream(e);
	}
}
